#!/usr/bin/env python
# encoding: utf-8


"""
@file: condition_converts.py
@time: 2017/2/27 下午8:06
"""

from mathsolver.functions.base import *
from sympy import symbols, sqrt
from mathsolver.functions.budengshi import common_opers as co
from itertools import permutations


# [已知正三角形ABC的顶点A(1,1),B(1,3),顶点C在第一象限],若点(x,y)在△ABC内部,则z=-x+y的取值范围是()
# 输出定点C
class SanJiaoXingDingDianCondition(BaseFunction):
    @staticmethod
    def quad_x_y_pm(quad_num):
        if quad_num == 1:
            return 1, 1
        elif quad_num == 2:
            return -1, 1
        elif quad_num == 3:
            return -1, -1
        elif quad_num == 4:
            return 1, -1
        else:
            raise Exception('wrong quad value')

    def solver(self, *args):
        self.label.add('点所在象限的条件')
        angle1, angle2 = [Symbol(obj.name) for obj in args[0].objs]
        other_angle = list(FiniteSet(*[Symbol(n) for n in args[1].value]) - FiniteSet(angle1, angle2))[0]
        angle1_point, angle2_point = args[0].sympify()
        x0, y0 = symbols('x0, y0')
        side_length = sqrt((angle1_point[0] - angle2_point[0]) ** 2 + (angle1_point[1] - angle2_point[1]) ** 2)
        eq1 = [(angle1_point[0] - x0) ** 2 + (angle1_point[1] - y0) ** 2, side_length ** 2]
        eq2 = [(angle2_point[0] - x0) ** 2 + (angle2_point[1] - y0) ** 2, side_length ** 2]
        eqs = [eq1, eq2]
        self.steps.append(['令' + new_latex(other_angle), '(%s, %s)' % (new_latex(x0), new_latex(y0))])
        self.steps.append(['由题意可知:', BaseEqs(eqs).printing()])
        x0_y0_values = co.solve_poly_eqs(BaseEqs(eqs))
        other_points = list(map(lambda values: (values[0][1], values[1][1]), x0_y0_values))
        verify_points = []
        # for p in other_points:
        #     x_value, y_value = p
        #     if x_value > 0 and y_value > 0:
        #         verify_points.append(p)
        quad_text = args[2].replace("-", "")
        quad = None
        if quad_text.find('第一象限') >= 0:
            quad = 1
        elif quad_text.find('第二象限') >= 0:
            quad = 2
        elif quad_text.find('第三象限') >= 0:
            quad = 3
        elif quad_text.find('第四象限') >= 0:
            quad = 4
        for p in other_points:
            x_value, y_value = p
            x_pm, y_pm = SanJiaoXingDingDianCondition.quad_x_y_pm(quad)
            if x_value * x_pm > 0 and y_value * y_pm > 0:
                verify_points.append(p)
        if len(verify_points) == 1:
            self.output.append(BasePoint({'name': str(other_angle), 'value': verify_points[0]}))
        else:
            x_symbol, y_symbol = Symbol("x_%s" % str(other_angle)), Symbol("y_%s" % str(other_angle))
        return self


# 已知正三角形ABC的顶点A(1,1),B(1,3),顶点C在第一象限,[若点(x,y)在△ABC内部,则z=-x+y的取值范围是()]
# 等价转换为不等式组输出
class SanJiaoXingNeiBuCondition(BaseFunction):
    @staticmethod
    def x_y_pm(quad):
        if quad == 1:
            return 1, 1
        elif quad == 2:
            return -1, 1
        elif quad == 3:
            return -1, -1
        elif quad == 4:
            return 1, -1
        else:
            raise Exception('wrong quad value')

    def solver(self, *args):
        self.label.add('点所在象限的条件')
        points = args[0].sympify()
        angle1, angle2, angle3 = symbols(','.join(sorted(map(str, args[0].sympify().keys()))))
        angle1_point = list(points[angle1])[0]
        angle2_point = list(points[angle2])[0]
        angle3_point = list(points[angle3])[0]
        center_point = ((angle2_point[0] + angle2_point[0] + angle3_point[0]) / 3,
                        (angle2_point[1] + angle2_point[1] + angle3_point[1]) / 3)
        ineqs = []
        line0 = co.line_two_point_eq(angle1_point, angle2_point)
        line0_left, line0_right = line0.sympify()
        line0_f = line0_left - line0_right
        if co.satisfied_ineqs(BaseIneqs([[line0_f, '>', '0']]), (('x', center_point[0]), ('y', center_point[1]))):
            ineqs.append([line0_f, '>', '0'])
        else:
            ineqs.append([line0_f, '<', '0'])
        line1 = co.line_two_point_eq(angle1_point, angle3_point)
        line1_left, line1_right = line1.sympify()
        line1_f = line1_left - line1_right
        if co.satisfied_ineqs(BaseIneqs([[line1_f, '>', '0']]), (('x', angle3_point[0]), ('y', center_point[1]))):
            ineqs.append([line1_f, '>', '0'])
        else:
            ineqs.append([line1_f, '<', '0'])
        line2 = co.line_two_point_eq(angle2_point, angle3_point)
        line2_left, line2_right = line2.sympify()
        line2_f = line2_left - line2_right
        if co.satisfied_ineqs(BaseIneqs([[line2_f, '>', '0']]), (('x', angle3_point[0]), ('y', center_point[1]))):
            ineqs.append([line2_f, '>', '0'])
        else:
            ineqs.append([line2_f, '<', '0'])
        self.steps.append(['原题目则等价于求满足不等式组', BaseIneqs(ineqs)])
        self.output.append(BaseIneqs(ineqs))
        return self


def quadl_info(point1, point2, point3, point4):
    """
    由四边形的四个顶点坐标，求出 1 四边形合法的的四个顶点;2 四边形每条边的直线方程以及该直线方程经过的两个顶点; 3 四边形的对角线的交点
    :param point1:
    :param point2:
    :param point3:
    :param point4:
    :return:
    """

    def is_quadl(tmp_point1, tmp_point2, tmp_point3, tmp_point4):
        """
        四个顶点是否是按合法的顺序组成的四边形
        :param tmp_point1:
        :param tmp_point2:
        :param tmp_point3:
        :param tmp_point4:
        :return:
        """
        line1 = co.line_two_point_eq(tmp_point1, tmp_point2)
        line1_slope = co.line_slope(line1)
        line2 = co.line_two_point_eq(tmp_point2, tmp_point3)
        line2_slope = co.line_slope(line2)
        line3 = co.line_two_point_eq(tmp_point3, tmp_point4)
        line3_slope = co.line_slope(line3)
        line4 = co.line_two_point_eq(tmp_point4, tmp_point1)
        line4_slope = co.line_slope(line4)
        if line1_slope == line3_slope and line2_slope == line4_slope:
            return True
        else:
            return False

    points = [point1, point2, point3, point4]
    points_per = permutations(points, 4)
    quadl_points_list = list(filter(lambda tmp_points: is_quadl(*tmp_points), points_per))
    quadl_points = quadl_points_list[0]
    point1, point2, point3, point4 = quadl_points
    lines = (
        (co.line_two_point_eq(point1, point2), (point1, point2)),
        (co.line_two_point_eq(point2, point3), (point2, point3)),
        (co.line_two_point_eq(point3, point4), (point3, point4)),
        (co.line_two_point_eq(point4, point1), (point4, point1)))
    diag_line1 = co.line_two_point_eq(point1, point3)
    diag_line2 = co.line_two_point_eq(point2, point4)
    inter_point = co.lines_intersections(BaseEqs([diag_line1.sympify(), diag_line2.sympify()]))[0]
    return lines, (diag_line1, diag_line2, (inter_point[1][0][1], inter_point[1][1][1]))


# print quadl_info((3, 4), (-1, 2), (4, -2), (0, -4))


# 已知▱ABCD的三个顶点为A(-1,2),B(3,4),C(4,-2),点(x,y)在▱ABCD的内部,则z=2x-5y的取值范围是()
class SiBianXingNeiBuCondition(BaseFunction):
    def solver(self, *args):
        self.label.add('可行域表示-三角形')
        point1, point2, point3, point4 = ([self.search(n).sympify() for n in args[0].value])  # 测试, 调规则的时候需要转换成这种格式
        lines, inter_point = quadl_info(point1, point2, point3, point4)
        diag_inter_point = inter_point[2]
        line1, line2, line3, line4 = map(lambda tmp_line: tmp_line[0], lines)
        new_lines = [line1, line2, line3, line4]
        ineqs = []
        for line in new_lines:
            line_left, line_right = line.sympify()
            line_f = line_left - line_right
            if co.satisfied_ineqs(BaseIneqs([[line_f, '>', '0']]),
                                  (('x', diag_inter_point[0]), ('y', diag_inter_point[1]))):
                ineqs.append([line_f, '>', '0'])
            else:
                ineqs.append([line_f, '<', '0'])
        self.steps.append(['原题目则等价于求满足不等式组', BaseIneqs(ineqs).printing()])
        self.output.append(BaseIneqs(ineqs))
        return self


if __name__ == '__main__':
    pass
    # print SanJiaoXingDingDianCondition(verbose=True).solver(BaseSymbolValue({'A': (1, 1), 'B': (1, 3)})).output[
    #     0].sympify()
    # print SanJiaoXingCondition(verbose=True).solver(BaseSymbolValue({'A': (1, 1), 'B': (1, 3)}), '第一象限')
    # print SanJiaoXingCondition(verbose=True).solver(BaseSymbolValue({'A': (1, 1), 'B': (1, 3)}), '第一象限')
